#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <syslog.h>
#include <string.h>
#include <signal.h>

#include "wtp.h"
#include "wtp_state.h"

int init_daemon()
{
	/* Our process ID and Session ID */
	pid_t pid, sid;

	/* Fork off the parent process */
	pid = fork();
	if (pid < 0) {
		exit(EXIT_FAILURE);
	}

	/* If we got a good PID, then
		we can exit the parent process. */
	if (pid > 0) {
		exit(EXIT_SUCCESS);
	}

	/* Change the file mode mask */
	umask(0);

	/* Open any logs here */

	/* Create a new SID for the child process */
	sid = setsid();
	if (sid < 0) {
		/* Log the failure */
		exit(EXIT_FAILURE);
	}

	/* Change the current working directory */
	if ((chdir("/tmp")) < 0) {
		/* Log the failure */
		exit(EXIT_FAILURE);
	}

	/* Close out the standard file descriptors */
	close(STDIN_FILENO);
	close(STDOUT_FILENO);
	close(STDERR_FILENO);

	return 0;
}

void disp_usage(int argc, char **argv)
{
    if (argc >=1) {
        printf("Usage: %s -h -nn", argv[0]);
        printf("  Options:n");
        printf("      -ntDon't fork off as a daemon.n");
        printf("      -htShow this help screen.n");
        printf("n");
    }
}

void signal_handler(int sig) {

    switch(sig) {
        case SIGHUP:
            syslog(LOG_WARNING, "Received SIGHUP signal.");
            break;
        case SIGTERM:
            syslog(LOG_WARNING, "Received SIGTERM signal.");
            break;
        default:
            syslog(LOG_WARNING, "Unhandled signal (%d) %s", sig, strsignal(sig));
            break;
    }
}
 
int main(int argc, char *argv[])
{
	char c;
	
	wtp_state_t wtp_state;

	/* */
	while( (c = getopt(argc, argv, "nh|help")) != -1) {
        switch(c){
            case 'h':
                disp_usage(argc, argv);
                exit(0);
                break;
            case 'n':
                init_daemon();
                break;
            default:
                disp_usage(argc, argv);
                exit(0);
                break;
        }
    }

	// Setup signal handling before we start
	/*
	signal(SIGHUP, signal_handler);
	signal(SIGTERM, signal_handler);
	signal(SIGINT, signal_handler);
	signal(SIGQUIT, signal_handler); */

	/* Daemon-specific initialization goes here */
	
	wtp_state_t (*state_func[])() = 
	{
		&wtp_state_idle,
		&wtp_state_discovery,
		&wtp_state_sulking,
		&wtp_state_dtls_setup,
		&wtp_state_authorize,
		&wtp_state_dtls_connect,
		&wtp_state_dtls_td,
		&wtp_state_join,
		&wtp_state_configure,
		&wtp_state_image_data,
		&wtp_state_data_check,
		&wtp_state_run,
		&wtp_state_reset,
		&wtp_state_dead
	};
	
	char *stats[] = {
		"Idle",
		"Discovery",
		"Sulking",
		"Dtls Setup",
		"Authorize",
		"Dtls Connect",
		"Dtls TD",
		"Join",
		"Configure",
		"Image Data",
		"Data Check",
		"Run",
		"Reset",
		"Dead"
	};
	
	wtp_state = WTP_STATE_IDLE;
	/* The Big Loop */
	while (1) {
		/* Do some task here ... */
		printf("state(%2d): %p\t%s\n", wtp_state, 
				state_func[wtp_state], stats[wtp_state]);
		wtp_state = state_func[wtp_state]();
		sleep(2);
	}

	//syslog(LOG_INFO, "%s daemon exiting", argv[0]);
	exit(EXIT_SUCCESS);
}
